package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Strategy;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.query.QueryObject;
import cn.wolfcode.wolf2w.repository.StrategyCatalogRepository;
import cn.wolfcode.wolf2w.service.IStrategyCatalogService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.PageUtils;
import cn.wolfcode.wolf2w.vo.CatalogVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class StrategyCatalogServiceImpl implements IStrategyCatalogService {

	@Autowired
	private StrategyCatalogRepository strategyCatalogRepository;
	@Autowired
	private MongoTemplate template;

	@Override
	public void save(StrategyCatalog strategyCatalog) {
		strategyCatalog.setId(null);
		strategyCatalogRepository.save(strategyCatalog);
	}

	@Override
	public void update(StrategyCatalog strategyCatalog) {
		strategyCatalogRepository.save(strategyCatalog);
	}

	@Override
	public void delete(String id) {
		strategyCatalogRepository.deleteById(id);
	}

	@Override
	public StrategyCatalog get(String id) {
		return strategyCatalogRepository.findById(id).orElse(null);
	}

	@Override
	public List<StrategyCatalog> list() {
		return strategyCatalogRepository.findAll();
	}

	@Override
	public Page<StrategyCatalog> query(QueryObject qo) {
		Query query = new Query();

		return PageUtils.page(template,query,StrategyCatalog.class, qo,Sort.by(Sort.Direction.ASC,"_id"));
	}

	public List<Map<String, Object>> queryGroupCatalog() {
		/*Query query = new Query();
		query.with(Sort.by(Sort.Direction.ASC, "destName" ));
		// 查询所有的分类,按照destName排序
		List<StrategyCatalog> strategyCatalogs = template.find(query,StrategyCatalog.class);
		// 存储最终的数据
		List<Map<String, Object>> catalogs = new ArrayList<>();
		// 遍历strategyCatalogs每次的destName
		String destName = "";

		// 存储 destName 和 mapList(同一个destName的所有分类)
		Map<String,Object> catalog = new HashMap<>();
		// 存储属于某个destName的mapList数据
		List<StrategyCatalog> mapList = new ArrayList<>();
		int i = 0;
		for (StrategyCatalog strategyCatalog : strategyCatalogs) {
			// 相等说明还是和上一次同一个destName
			if(destName.equals(strategyCatalog.getDestName())){
				// 把catalog添加到同一个destName的mapList里
				mapList.add(strategyCatalog);
			}else{//和上一次不是同一个destName
				// 不是第一次就执行
				if(!"".equals(destName)){
					// 上一个destName的最后一步操作
					// 把mapList设置到map中,和把map添加到catalogs
					catalog.put("mapList",mapList);
					catalogs.add(catalog);
					// 清空
					mapList = new ArrayList<>();
					catalog = new HashMap<>();
				}
				// 把destName添加到map中,同一个destName只添加一次
				destName = strategyCatalog.getDestName();
				catalog.put("destName",destName);
				// 把mapList设置到map中
				mapList.add(strategyCatalog);
			}
			i++;
			// 如果是最后一次,把mapList设置到map中,和把map添加到catalogs
			// 最后一个destName的最后一步操作
			if(i==strategyCatalogs.size()){
				catalog.put("mapList",mapList);
				catalogs.add(catalog);
			}
		}
		return catalogs;*/
		// 存储所有数据的List
		List<Map<String, Object>> catalogs = new ArrayList<>();
		// 查询所有的分类
		List<StrategyCatalog> list = this.list();
		List<String> destNames = new ArrayList<>();
		// 遍历分类,提取目的地名字,不要重复的
		for (StrategyCatalog strategyCatalog : list) {
			if(!destNames.contains(strategyCatalog.getDestName())){
				destNames.add(strategyCatalog.getDestName());
			}
		}
		// 遍历目的地的名字
		for (String destName : destNames) {
			Map<String, Object> map = new HashMap<>();
			// 拿到当前目的地的所有分类
			List<StrategyCatalog> mapList = strategyCatalogRepository.findCatalogsByDestName(destName);
			map.put("destName", destName);
			map.put("mapList", mapList);
			// 把当次遍历的数据塞到List里
			catalogs.add(map);
		}
		return catalogs;
	}
	@Override
	public List<CatalogVO> groupList() {
		List<CatalogVO> list = new ArrayList<>();
		TypedAggregation<StrategyCatalog> agg = Aggregation.newAggregation(StrategyCatalog.class,
				Aggregation.group("destName").
						push("name").as("names").
						push("id").as("ids")
		);
		AggregationResults<Map> result = template.aggregate(agg,Map.class);
		List<Map> datas = result.getMappedResults();
		for (Map data : datas) {
			CatalogVO vo = new CatalogVO();

			vo.setDestName(data.get("_id").toString());

			List<Map<String, Object>> mm = new ArrayList<>();
			List<Object> names = (List<Object>) data.get("names");
			List<Object> ids = (List<Object>) data.get("ids");
			for (int i = 0;i < names.size(); i++) {
				Map<String, Object> vv = new HashMap<>();
				String name = names.get(i).toString();
				String id = ids.get(i).toString();
				vv.put("id", id);
				vv.put("name", name);
				mm.add(vv);
			}
			vo.setMapList(mm);
			list.add(vo);
		}
		return list;
	}

	@Override
	public List<StrategyCatalog> queryCatalogsByDestId(String destId) {
		// 根据传入的目的地 id查询对应的攻略分类
		List<StrategyCatalog> strategyCatalogs = strategyCatalogRepository.findCatalogsByDestId(destId);

		// 迭代器遍历每一个分类
		Iterator<StrategyCatalog> it = strategyCatalogs.iterator();
		while (it.hasNext()){
			StrategyCatalog strategyCatalog = it.next();
			Query query = new Query();
			query.addCriteria(Criteria.where("state").is(Strategy.STATE_PUBLISH));
			query.addCriteria(Criteria.where("catalogId").is(strategyCatalog.getId()));
			// 查询每个分类下的为攻略
			List<Strategy> strategies = template.find(query, Strategy.class);
			// 把攻略设置到分类里
			if(strategies.size() == 0){
				it.remove();
				continue;
			}
			strategyCatalog.setStrategies(strategies);
		}

		return strategyCatalogs;
	}
}
